package de.medieninf.android.sensimg;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class SettingsActivity extends Activity {
	final static String TAG = "settings";
	final static int DIALOG_HOSTPORT_SEND = 1;
	final static int DIALOG_HOSTPORt_RETRIEVE = 2;
	
	SensorService mSensorService;
	
	Spinner mSpinnerSelectHostPortSend;
	Button mButtonAddHostPortSend;
	Spinner mSpinnerSelectHostPortRetrieve;
	Button mButtonAddHostPortRetrieve;
	Spinner mSpinnerKeyMapping;
	int positionKeyMapping;
	EditText mEditTextMapFrom;
	EditText mEditTextMapTo;
	Button mButtonAddMapping;
	Button mButtonUpdateMapping;
	Button mButtonDeleteMapping;
	Button mButtonOk;
	Button mButtonCancel;

	
	OnClickListener mListenerAddHostPort = new OnClickListener() {
		@Override
		public void onClick(View v) {
			if (v == mButtonAddHostPortSend)
				showDialog(DIALOG_HOSTPORT_SEND);
			else if (v == mButtonAddHostPortRetrieve)
				showDialog(DIALOG_HOSTPORt_RETRIEVE);
		}
	};
		
	OnClickListener mListenerOk = new OnClickListener() {
		@SuppressWarnings("unchecked")
		@Override
		public void onClick(View v) {
			if (mSensorService != null) {
				mSensorService.setHostPortSend((String) mSpinnerSelectHostPortSend.getSelectedItem());
				mSensorService.setHostPortRetrieve((String) mSpinnerSelectHostPortRetrieve.getSelectedItem());
				ArrayAdapter<String> adapter = (ArrayAdapter<String>) mSpinnerKeyMapping.getAdapter();
				HashMap<Character, Character> mapping = new HashMap<Character, Character>();
				for (int i=0; i < adapter.getCount(); i++) {
					String entry = adapter.getItem(i);
					mapping.put(entry.charAt(0), entry.charAt(2));					
				}
				mSensorService.getKeyboardState().setTranslateMap(mapping);
				//TODO actually, that is ugly - use the Map all the time
			}
			// Log.v(TAG, "oking");
			unbindService(mConnection);
			mSensorService = null;
			finish();
		}
	};
	
	OnClickListener mListenerCancel = new OnClickListener() {
		@Override
		public void onClick(View v) {
			// Log.v(TAG, "canceling");
			unbindService(mConnection);
			mSensorService = null;
			finish();
		}
	};
	
	OnClickListener mListenerMapping = new OnClickListener() {
		@SuppressWarnings("unchecked")
		@Override
		public void onClick(View v) {
			Log.v(TAG, "mListenerMapping");
			ArrayAdapter<String> adapter = (ArrayAdapter<String>) mSpinnerKeyMapping.getAdapter();
			if (v.equals(mButtonAddMapping)) {
				final String newEntry = "a:a";
				if (adapter.getPosition(newEntry) != -1) {
					Toast toast = Toast.makeText(SettingsActivity.this, "There is already a new one", Toast.LENGTH_LONG);
					toast.show();
					return;
				}
				int position = adapter.getCount();
				adapter.insert(newEntry, position);
				// Log.v(TAG, "setting to position " + position);
				mSpinnerKeyMapping.setSelection(position);
				// mappingItemSelected.onItemSelected(null, null, position, -1L);
				
			} else if (v.equals(mButtonUpdateMapping)) {
				String from = mEditTextMapFrom.getText().toString();
				String to = mEditTextMapTo.getText().toString();
				if (from.length() != 1 || to.length() != 1) {
					Toast toast = Toast.makeText(SettingsActivity.this, "Need to be one character each", Toast.LENGTH_LONG);
					toast.show();
					return;
				}
				String entry = from + ":" + to;
				adapter.remove(adapter.getItem(positionKeyMapping));
				adapter.insert(entry, positionKeyMapping);
			} else if (v.equals(mButtonDeleteMapping)) {
				adapter.remove(adapter.getItem(positionKeyMapping));
				mappingItemSelected.onItemSelected(null, null, 0, -1L); // reset
			} else {
				// Log.v(TAG, "mListenerMapping, no matching View");
			}
				
		}
	};
	
	private OnItemSelectedListener mappingItemSelected = new OnItemSelectedListener() {
		@Override
		public void onItemSelected(AdapterView<?> parent, View c, int position, long id) {
			positionKeyMapping = position;
			String mapping = (String) mSpinnerKeyMapping.getAdapter().getItem(position);
			if (mapping.length() != 3)
				return;
			mEditTextMapFrom.setText(""+mapping.charAt(0)); // without ""+ there is an exception
			mEditTextMapTo.setText(""+mapping.charAt(2));
		}
		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
			mEditTextMapFrom.setText("");
			mEditTextMapTo.setText("");
		}
	};

    private ServiceConnection mConnection = new ServiceConnection() {
    	@Override
        public void onServiceConnected(ComponentName className, IBinder service) {
    		// Log.v(TAG, "trying to bind SensorService");
            mSensorService = ((SensorService.LocalBinder) service).getService();
            updateHostPorts();
            updateKeyMapping();
        }
		@Override
		public void onServiceDisconnected(ComponentName name) {
    		// Log.v(TAG, "SensorService is disconnected");
			mSensorService = null;
		}
    };
    
    private void updateHostPorts() {
    	List<String> hps = mSensorService.getHostPortsSend();
    	ArrayAdapter<String> adapter = new ArrayAdapter<String>(mSensorService, 
    			android.R.layout.simple_spinner_item, 
    			hps);
    	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    	mSpinnerSelectHostPortSend.setAdapter(adapter);
    	mSpinnerSelectHostPortSend.setSelection(mSensorService.getCurrrentIndexSend());
    	hps = mSensorService.getHostPortsRetrieve();
    	adapter = new ArrayAdapter<String>(mSensorService, 
    			android.R.layout.simple_spinner_item, 
    			hps);
    	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    	mSpinnerSelectHostPortRetrieve.setAdapter(adapter);
    	mSpinnerSelectHostPortRetrieve.setSelection(mSensorService.getCurrrentIndexRetrieve());
    }

    private void updateKeyMapping() {
    	HashMap<Character, Character> mapping = mSensorService.getKeyboardState().getTranslateMap();
    	List<String> km = new ArrayList<String>();
    	for (Map.Entry<Character, Character> entry : mapping.entrySet()) {
    		km.add(entry.getKey() + ":" + entry.getValue());
    	}
    	ArrayAdapter<String> adapter = new ArrayAdapter<String>(mSensorService, 
    			android.R.layout.simple_spinner_item, 
    			km);
    	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    	mSpinnerKeyMapping.setAdapter(adapter);
    	mSpinnerKeyMapping.setOnItemSelectedListener(mappingItemSelected);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.settings);
    	
    	mSpinnerSelectHostPortSend = (Spinner) findViewById(R.id.select_hostport_send);
    	mButtonAddHostPortSend = (Button) findViewById(R.id.add_hostport_send);
    	mButtonAddHostPortSend.setOnClickListener(mListenerAddHostPort);
    	mSpinnerSelectHostPortRetrieve = (Spinner) findViewById(R.id.select_hostport_retrieve);
    	mButtonAddHostPortRetrieve = (Button) findViewById(R.id.add_hostport_retrieve);
    	mButtonAddHostPortRetrieve.setOnClickListener(mListenerAddHostPort);
    	mSpinnerKeyMapping = (Spinner) findViewById(R.id.select_mapping);
    	positionKeyMapping = 0;
    	mEditTextMapFrom = (EditText) findViewById(R.id.edit_from);
    	mEditTextMapTo = (EditText) findViewById(R.id.edit_to);
    	mButtonAddMapping = (Button) findViewById(R.id.button_add_mapping);
    	mButtonAddMapping.setOnClickListener(mListenerMapping);
    	mButtonUpdateMapping = (Button) findViewById(R.id.button_update_mapping);
    	mButtonUpdateMapping.setOnClickListener(mListenerMapping);
    	mButtonDeleteMapping = (Button) findViewById(R.id.button_delete_mapping);
    	mButtonDeleteMapping.setOnClickListener(mListenerMapping);
    	mButtonOk = (Button) findViewById(R.id.ok_hostport);
    	mButtonOk.setOnClickListener(mListenerOk);
    	mButtonCancel = (Button) findViewById(R.id.cancel_hostport);
    	mButtonCancel.setOnClickListener(mListenerCancel);
    	
        bindService(
        		new Intent(this, SensorService.class),
                mConnection,
                Context.BIND_AUTO_CREATE);
    }
    
    @Override
    protected void onPause() {
    	if (mSensorService != null) {
    		unbindService(mConnection);
    	}
    	super.onPause();
    }
    
    @Override
    protected Dialog onCreateDialog(int id) {
        LayoutInflater factory = LayoutInflater.from(this);
    	switch(id) {
    	case DIALOG_HOSTPORT_SEND: 
    		{
    			final View textEntryView = factory.inflate(R.layout.dialog_add_send, null);
    			final EditText editText = (EditText) textEntryView.findViewById(R.id.hostport_edit_send);
    			AlertDialog.Builder builder = new AlertDialog.Builder(this);
    			builder.setTitle(R.string.dialog_title_add_hostport_send);
    			builder.setView(textEntryView);
    			builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
    				@Override
    				public void onClick(DialogInterface dialog, int which) {
    					String entry = editText.getText().toString();
    					Toast toast = Toast.makeText(SettingsActivity.this, "couldn't save " + entry, Toast.LENGTH_LONG);
    					if (mSensorService != null) {
    						if (mSensorService.setHostPortSend(entry)) {
    							toast = Toast.makeText(SettingsActivity.this, "saved entry " + entry, Toast.LENGTH_LONG);
    						}
    					}
    					toast.show();
    				}
    			});
    			builder.setCancelable(true);
    			if (mSensorService != null) {
    				editText.setText(mSensorService.getCurrentHostSend()+":"+mSensorService.getCurrentPortSend());
    			}
        		return builder.create();
    		}
    	case DIALOG_HOSTPORt_RETRIEVE:
    		{
    			final View textEntryView = factory.inflate(R.layout.dialog_add_retrieve, null);
    			final EditText editText = (EditText) textEntryView.findViewById(R.id.host_edit_retrieve);
    			AlertDialog.Builder builder = new AlertDialog.Builder(this);
    			builder.setTitle(R.string.dialog_title_add_hostport_retrieve);
    			builder.setView(textEntryView);
    			builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
    				@Override
    				public void onClick(DialogInterface dialog, int which) {
    					String entry = editText.getText().toString();
    					Toast toast = Toast.makeText(SettingsActivity.this, "couldn't save " + entry, Toast.LENGTH_LONG);
    					if (mSensorService != null) {
    						if (mSensorService.setHostPortRetrieve(entry)) {
    							toast = Toast.makeText(SettingsActivity.this, "saved entry " + entry, Toast.LENGTH_LONG);
    						}
    					}
    					toast.show();
    				}
    			});
    			builder.setCancelable(true);
    			if (mSensorService != null) {
    				editText.setText(mSensorService.getCurrentHostRetrieve()+":"+mSensorService.getCurrentPortRetrieve());
    			}
    			return builder.create();
    		}
    	}
    	return super.onCreateDialog(id);
    }
}
